package com.acme.bankapp.service.bank.listener.email;

import java.util.LinkedList;
import java.util.List;

/**
 * @author Alexander Kotov (kotov.alex.22@gmail.com)
 */
public class BankBlockingQueue<T> {
    private final int maxQueueSize;
    private final List<T> queue = new LinkedList<>();
    private volatile boolean isClosed;

    public BankBlockingQueue(int maxQueueSize) {
        this.maxQueueSize = maxQueueSize;
    }

    public void close() {
        synchronized (queue) {
            isClosed = true;
        }
    }

    public void add(T elem) throws InterruptedException, IllegalStateException {
        synchronized (queue) {
            if (isClosed) {
                throw new IllegalStateException("Queue is closed. Can't add Element.");
            } else {
                while (queue.size() == maxQueueSize) {
                    queue.wait();
                }
                queue.add(elem);
                queue.notifyAll();
            }
        }
    }

    public T get() throws InterruptedException {
        synchronized (queue) {
            while (queue.isEmpty()) {
                queue.wait();
            }
            T result = queue.remove(0);
            queue.notifyAll();
            return result;
        }
    }

    public T compareAndGet() {
        synchronized (queue) {
            if (queue.isEmpty()) {
                return null;
            } else {
                T elem = queue.remove(0);
                queue.notifyAll();
                return elem;
            }
        }
    }
}
